home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
pascal
/
gsdbloo.exe
/
GS_DBNDX.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-03-01
|
56KB
|
1,312 lines
unit GS_DBNdx;
{-----------------------------------------------------------------------------
dBase III Index Handler
GS_DBNdx Copyright (c) Richard F. Griffin
15 November 1990
102 Molded Stone Pl
Warner Robins, GA 31088
-------------------------------------------------------------
This unit handles the objects for all dBase III index (.NDX)
operations.
changes:
16 Nov 90 - Modified KeyUpdate sub-procedure KeyInsert to
test for end-of-file during search for key.
22 Apr 91 - Modified SetMatchValue to be a method. This will
ensure consistency in building character and numeric
values. Also modified throughout to ensure the full
length was loaded into Ndx_Key_St for a field rather
than just moving length(Work_Key) characters.
Also added comments for KeyUpdate procedures.
02 May 91 - Added an IndexSignature constant so the GS_dBase unit
can confirm this unit is the dBase III index unit.
01 Aug 91 - Replaced string compare in DoMatchValue with call to
GS_Sort_Compare for speed increase.
15 Dec 91 - Fixed error in Ndx_GetRecPage that caused error in
attempt to read Bttm_Record.
02 Feb 92 - Added call to KeyLocRec in main part of KeyUpdate.
This allows multiple indexes to be used. In the past,
the program assumed the index was pointing to the
current record. There is a sacrifice in update
speed, however.
19 Feb 92 - Embedded cache into Ndx_Get and Ndx_Put. A number
of node images will be stored to memory. This will
be treated as a stack, where the last page accessed
will be pushed to the top and new nodes will use the
bottom image. They will replace the old image and
push to the top. This allows the most active nodes to
remain in memory, with less active nodes being swapped
out. This also added a Ndx_Flush method to write all
updated nodes to disk on demand, such as at closing.
Added KeyBOF flag for test for access beyond top of
file.
25 Feb 92 - Added call to unit GS_DBL.PAS to handle the routines
to create and compare floating point types used in
dBase indexes. These routines save 10K of memory over
the $N,E option for numeric coprocessor emulation.
------------------------------------------------------------------------------}
{$D-}
interface
uses
GS_Dbl, {handle double types}
GS_Strng, {String handler routines}
GS_Sort, {Sort/Compare routine}
GS_Error, {Error handler routines}
GS_FileH; {File handler routines}
const
NdxBufSize = 4096;
NdxBufferedPages = 32;
IndexSignature = 'NDX3';
type
{
┌──────────────────────────────────────────────────────────┐
│ This record type describes the index file header. │
│ This is a 512-byte block that is located at the │
│ beginning of the index file. Refer to Appendix C │
│ for a description of the fields. │
└──────────────────────────────────────────────────────────┘
}
GS_Indx_Head = Record
Root : Longint;
Next_Blk : Longint;
Unknwn1 : Longint;
Key_Lgth : Integer;
Max_Keys : Integer;
Data_Typ : Integer;
Entry_Sz : Integer;
Unknwn2 : Longint;
Key_Form : array [0..487] of char;
end;
{
┌──────────────────────────────────────────────────────────┐
│ This record type describes the index file node header. │
│ Each node is a 512-byte block that is used as nodes │
│ to store keys and pointers. Refer to Appendix C │
│ for a description of the fields. │
└──────────────────────────────────────────────────────────┘
}
GS_Indx_Data = Record
Entry_Ct : Integer;
Unknwn1 : Integer;
Data_Ary : array [0..507] of byte;
{Memory array holding key entries}
Filler1 : array [0..255] of byte;
{Filler for possible overflow during}
{insert mode.}
end;
GS_Indx_EntPtr = ^GS_Indx_Etry; {Pointer of type GS_Indx_Etry. Will}
{be used to reference key entries }
{from GS_Indx_Data.Data_Ary.}
{
┌──────────────────────────────────────────────────────────┐
│ This record type describes the index file key entries. │
│ Refer to Appendix C for a description of each field. │
└──────────────────────────────────────────────────────────┘
}
GS_Indx_Etry = Record
Block_Ax : Longint;
Recrd_Ax : Longint;
Char_Fld : array [1..255] of char;
end;
{
┌────────────────────────────────────────────────────────┐
│ Work table used to step through nodes. The previous │
│ nodes must be saved for finding the next or previous │
│ record during sequential reads. │
└────────────────────────────────────────────────────────┘
}
GS_Indx_Tabl = Record
Page_No : Longint; {Disk block holding node info}
Etry_No : Longint; {Last entry used in node}
Last_One : Longint; {Number of keys in this node }
Node_Pag : Boolean; {True for non-leaf nodes}
end;
GS_DiskPagPtr = ^GS_DiskPagBfr;
GS_DiskPagBfr = array[0..511] of byte;
GS_DiskTblPtr = ^GS_DiskTblPag;
GS_DiskTblPag = record
BlkNum : longint;
BlkWrt : boolean;
BlkPtr : GS_DiskPagPtr;
end;
GS_Indx_LPtr = ^GS_dBase_IX; {Pointer to object. Used by GS_dBase_DB}
{
┌─────────────────────────────────┐
│ GS_dBase_IX Object Definition │
└─────────────────────────────────┘
}
GS_dBase_IX = object
Ndx_Name : String[64]; {File name of index file}
Ndx_Hdr : GS_Indx_Head; {Index header information}
Ndx_File : file; {File type for index file}
Ndx_Tabl : array [0..25] of GS_Indx_Tabl;
{Array of 25 table entries to hold}
{the trail of non-leaf nodes that are}
{traversed during a key search. This }
{table is needed to track positions for}
{sequential reads (next and previous).}
Ndx_Lvl : integer; {Holds counter into Ndx_Tabl}
Ndx_Data : GS_Indx_Data; {Node header information}
Ndx_Pntr : GS_Indx_EntPtr; {Pointer to key entry information}
Ndx_Key_St : string[127]; {Holds last key value found on call to}